﻿
namespace Might.Infrastructure.ModelicaDOM.Expressions

open System

type ComponentReferenceParts =
    | Name of string
    | ArrayIndex of int

and ComponentReference = class        
    
    val mutable _parts:ComponentReferenceParts list    
    new(parts) = {
        _parts = parts
    }      
end

type RelationalOperator =
    | Less = 0
    | LessOrEqual = 1
    | Greater = 2
    | GreaterOrEqual = 3
    | Equal = 4
    | NotEqual = 5
    
type AdditionOperator =
    | Add = 0
    | Substract = 1
    | ElementWiseAdd = 2
    | ElementWiseSubstract = 3
    
type MultiplicationOperator =
    | Multiplication = 0
    | Division = 1
    | ElementWiseMultiplication = 2
    | ElementWiseDivision = 3
    
type PowerOperator = 
    | Power = 0
    | ElementWisePower = 1

type Expression =
    | SimpleExpressionDef of SimpleExpression
    | IfExpressionDef of IfExpression
    | EmptyExpression
and IfExpression = class
    new() = {}
end

and SimpleExpression =
    | Single of LogicalExpression
    | Pair of LogicalExpression * LogicalExpression
    | Triplet of LogicalExpression * LogicalExpression * LogicalExpression

and LogicalExpression = class
    val mutable _termList : LogicalTerm list
    new() = {
        _termList = []
    }
end

and LogicalTerm = class
    val mutable _factorList : LogicalFactor list
    new() = {
        _factorList = []
    }
end

and LogicalFactor = class
    val mutable _negation:bool
    val mutable _relation: Relation
    new() = {
        _relation = new Relation()
        _negation = false
    }
end

and Relation = class
    val mutable _arithmeticExpressionLeft: ArithmeticExpression
    val mutable _arithmeticExpressionRight: ArithmeticExpression option
    val mutable _relOp: RelationalOperator option
    
    new() ={
        _arithmeticExpressionLeft = new ArithmeticExpression()
        _arithmeticExpressionRight = None
        _relOp = None    
    }
end

and ArithmeticExpression = class
    val mutable _unaryAddOp: AdditionOperator option
    val mutable _term :Term
    val mutable _operatorTermList: ((AdditionOperator * Term) list) option
    new() = {
        _unaryAddOp = None
        _term = new Term()
        _operatorTermList = None    
   } 
end

and Term = class    
    val mutable _factor: Factor
    val mutable _operatorFactorList: ((MultiplicationOperator * Factor) list) option
    new() = {        
        _factor = new Factor()
        _operatorFactorList = None    
   } 
end

and Factor = class    
    val mutable _primaryLeft: Primary
    val mutable _powerOperator: PowerOperator option
    val mutable _primaryRight: Primary option
    new() = {        
        _primaryLeft = Primary.EmptyPrimary
        _powerOperator = None
        _primaryRight = None        
   } 
end
    
and Primary = 
    | IntLiteral of int
    | FloatLiteral of double
    | StringLiteral of string
    | BoolLiteral of bool
    | FunctionCallDef of FunctionCall
    | ComponentReferenceDef of ComponentReference
    | OutputExpressionListDef  // postoponed until... sometime, not needed for now
    | WeirdExpressionList // postoponed until... sometime, not needed for now
    | ArrayConstructionDef of FunctionArgs  
    | EmptyPrimary   
    
and FunctionCall = class
    val mutable _funcName: string
    val mutable _funcArgs:FunctionArgs option
    new() = {
        _funcName = String.Empty
        _funcArgs = None
    }
end
and FunctionArgs =
    | ExpressionForIndices of (Expression list) * ForIndices
    | PositionalAndNamed of (Expression list) * (NamedArgument list)
    
and NamedArgument = class
    val mutable _argumentName:string
    val mutable _argumentValue: Expression
    new() = {
        _argumentName = String.Empty
        _argumentValue = Expression.EmptyExpression
    }
end

and ForIndices() = class
    [<DefaultValue>]
    val mutable _indices : (string  * (Expression option)) list        
end